﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenTK;
using OpenTK.Input;
using OpenTK2.Graphics;

namespace MazeRunner.GameState
{
	public class GameCore
	{
		private Maze currentMaze;
		private Player player;
		private Billboard test; 

		public Vector3 CameraPos { get { return new Vector3(player.XPos * 2, 0, player.ZPos * 2); } }
		//public Vector3 CameraView { get { return new Vector3(player.XView + player.XPos, 0, player.ZView + player.ZPos); } }
		public float XRot { get { return player.XRot; } }
		private float lastx;

		public GameCore()
		{
			player = new Player();
			player.XView = 0;
			player.ZView = 1;
			player.XRot = 0;

			test = new Billboard();

			lastx = 0;
			Random r = new Random();
			currentMaze = MazeCreator.CreateRandomMaze(100, 100, 30, 15, 4, 2, 2, 10, r);
			Point startingPos = MazeCreator.FindSpawnLocationsAndOptimizeMaze(currentMaze, r);

			player.XPos = startingPos.X;
			player.ZPos = startingPos.Y;

			test.xPos = player.XPos - 2;
			test.yPos = player.ZPos;
		}

		public void Draw()
		{
			currentMaze.DrawMaze();
			test.Draw(player.XRot - 135);
		}

		public void Update(GameWindow gameWindow, FrameEventArgs e)
		{
			float movementRate = (float)(e.Time*10);
			if (gameWindow.Keyboard[Key.W])
			{
				float xrotrad = (player.XRot / 180) * 3.141592654f;
				float xMove = (float)Math.Sin(xrotrad) * movementRate;
				float zMove = (float)Math.Cos(xrotrad) * movementRate * -1;
				HandleCollision(xMove, zMove);
			}
			else if (gameWindow.Keyboard[Key.S])
			{
				float xrotrad = (player.XRot / 180) * 3.141592654f;
				float xMove = (float)Math.Sin(xrotrad) * movementRate * -1;
				float zMove = (float)Math.Cos(xrotrad) * movementRate;
				HandleCollision(xMove, zMove);
			}
			if (gameWindow.Keyboard[Key.A])
			{
				float xrotrad = ((player.XRot + 90) / 180) * 3.141592654f;
				float xMove = (float)Math.Sin(xrotrad) * movementRate * -1;
				float zMove = (float)Math.Cos(xrotrad) * movementRate;
				HandleCollision(xMove, zMove);
			}
			else if (gameWindow.Keyboard[Key.D])
			{
				float xrotrad = ((player.XRot + 90) / 180) * 3.141592654f;
				float xMove = (float)Math.Sin(xrotrad) * movementRate;
				float zMove = (float)Math.Cos(xrotrad) * movementRate * -1;
				HandleCollision(xMove, zMove);
			}
		}

		public void MouseMove(MouseMoveEventArgs e)
		{
			float diffx = e.X - lastx;
			lastx = e.X;

			player.XRot += diffx;
		}

		private void HandleCollision(float xMove, float zMove)
		{
			int convertedX = (int)player.XPos;
			int convertedZ = (int)player.ZPos;

			if (xMove >= 0)
			{
				if (currentMaze.MazeItems[convertedX + 1, convertedZ] == MazeItem.Wall)
				{
					if (player.XPos + xMove > 0.4f + convertedX)
					{
						player.XPos = convertedX + 0.4f;
					}
					else
					{
						player.XPos += xMove;
					}
				}
				else
				{
					player.XPos += xMove;
				}
			}
			else
			{
				if (currentMaze.MazeItems[convertedX - 1, convertedZ] == MazeItem.Wall)
				{
					if (player.XPos + xMove < 0.6f + convertedX)
					{
						player.XPos = convertedX + 0.6f;
					}
					else
					{
						player.XPos += xMove;
					}
				}
				else
				{
					player.XPos += xMove;
				}
			}
			if (zMove >= 0)
			{
				if (currentMaze.MazeItems[convertedX, convertedZ + 1] == MazeItem.Wall)
				{
					if (player.ZPos + zMove > 0.4f + convertedZ)
					{
						player.ZPos = convertedZ + 0.4f;
					}
					else
					{
						player.ZPos += zMove;
					}
				}
				else
				{
					player.ZPos += zMove;
				}
			}
			else
			{
				if (currentMaze.MazeItems[convertedX, convertedZ - 1] == MazeItem.Wall)
				{
					if (player.ZPos + zMove < 0.6f + convertedZ)
					{
						player.ZPos = convertedZ + 0.6f;
					}
					else
					{
						player.ZPos += zMove;
					}
				}
				else
				{
					player.ZPos += zMove;
				}
			}
			test.xPos = player.XPos - 2;
			test.yPos = player.ZPos;
		}
	}
}
